/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package runner;

import RunnerGameStates.BalinerasGameState;
import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.light.PointLight;
import com.jme.math.*;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.*;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.LightState;
import com.jme.system.DisplaySystem;
import com.jme.util.GameTaskQueueManager;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.editors.swing.settings.GameSettingsPanel;
import com.jmex.game.StandardGame;
import com.jmex.game.state.DebugGameState;
import com.jmex.game.state.GameStateManager;
import com.model.md5.ModelNode;
import com.model.md5.importer.MD5Importer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;
import modelos.*;

/**
 *
 * @author Administrador
 */
public class EscenaPrincipal {

  private MainMenuState mMMenu;
  private StandardGame game;
  private DebugGameState state;
  private BalinerasGameState balinerasState;

  /*Url md5*/
  private URL mesh;
  private URL animacion;

  public EscenaPrincipal() {
    game = new StandardGame("Criollolimpicos");
    try {
      if (GameSettingsPanel.prompt(game.getSettings())) {
        game.start();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    /****************************Estado de juego para balineras*******************************/
    balinerasState = new BalinerasGameState("balineras");
    /*****************************************************************************************/
    /*Inicializar la cámara*/
    /**/

    /*Pasar cámara al renderer*/
    /**/

    /*Inicializar los keyBindings*/
    /**/
    /*******************************Para cargar modelos Collada*******************************/
    //Node colladaModelNode = ColladaModelLoader.loadModel("wasminto.DAE");
    /*********************************Modelos Collada cargados********************************/
    /*********************************Para cargar modelos 3DS*********************************/
    ModelConverter.load3ds("modelos", "");
    Spatial carrito = null;
    Spatial wasminton = null;
    Spatial numinton = null;
    Spatial estadio = null;
    //URL carritoUrl = ModelConverter.class.getClassLoader().getResource("modelos/carrito.jme");
    URL wasmintonUrl = ModelConverter.class.getClassLoader().getResource("modelos/wasminto.jme");
    URL numintonUrl = ModelConverter.class.getClassLoader().getResource("modelos/numinton.jme");
    URL estadioUrl = ModelConverter.class.getClassLoader().getResource("modelos/estadio.jme");
    mesh = ModelConverter.class.getClassLoader().getResource("modelos/wasminto.md5mesh");
    animacion = ModelConverter.class.getClassLoader().getResource("modelos/wasminto.md5anim");
    //File modeloCarrito = new File(carritoUrl.getPath().replaceAll("%20", " "));
    File modeloWasminton = new File(wasmintonUrl.getPath().replaceAll("%20", " "));
    File modeloNuminton = new File(numintonUrl.getPath().replaceAll("%20", " "));
    File modeloEstadio = new File(estadioUrl.getPath().replaceAll("%20", " "));
    File wasmintonMD5 = new File(mesh.getPath().replaceAll("%20", " "));
    File wamintonMD5Anim = new File(animacion.getPath().replaceAll("%20", " "));
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();



    try {
      FileInputStream modelReader;// = new FileInputStream(modeloCarrito);
      int modelByte;

      modelReader = new FileInputStream(modeloWasminton);
      while ((modelByte = modelReader.read()) != -1) {
        outStream.write(modelByte);
      }
      modelReader.close();
      ByteArrayInputStream convertedIn = new ByteArrayInputStream(outStream.toByteArray());
      convertedIn = new ByteArrayInputStream(outStream.toByteArray());
      wasminton = (Spatial) BinaryImporter.getInstance().load(convertedIn);

      outStream.reset();

      modelReader = new FileInputStream(modeloNuminton);
      while ((modelByte = modelReader.read()) != -1) {
        outStream.write(modelByte);
      }
      modelReader.close();
      convertedIn = new ByteArrayInputStream(outStream.toByteArray());
      numinton = (Spatial) BinaryImporter.getInstance().load(convertedIn);

      outStream.reset();

      modelReader = new FileInputStream(modeloEstadio);
      while ((modelByte = modelReader.read()) != -1) {
        outStream.write(modelByte);
      }
      modelReader.close();
      convertedIn = new ByteArrayInputStream(outStream.toByteArray());
      estadio = (Spatial) BinaryImporter.getInstance().load(convertedIn);
      /*Carga de los modelos md5*/
      MD5Importer.getInstance().loadMesh(this.mesh, "Mesh");
      MD5Importer.getInstance().load(this.mesh, "Mesh", this.animacion, "Animation", 1);

    } catch (FileNotFoundException ex) {
      Logger.getLogger(EscenaPrincipal.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(EscenaPrincipal.class.getName()).log(Level.SEVERE, null, ex);
    }

    /*carrito.setModelBound(new BoundingBox());
    carrito.updateModelBound();
    carrito.setLocalTranslation(Vector3f.ZERO);*/

    ModelNode model = MD5Importer.getInstance().getModelNode();
    //model.getLocalRotation().fromAngleAxis((float) Math.toRadians(90), Vector3f.UNIT_Z);
    model.setModelBound(new BoundingBox());
    model.updateModelBound();
    model.setLocalTranslation(Vector3f.ZERO);

    wasminton.setModelBound(new BoundingBox());
    wasminton.updateModelBound();
    wasminton.setLocalTranslation(Vector3f.ZERO);

    numinton.setModelBound(new BoundingBox());
    numinton.updateModelBound();
    numinton.setLocalTranslation(Vector3f.ZERO);

    estadio.setModelBound(new BoundingBox());
    estadio.updateModelBound();
    estadio.setLocalTranslation(Vector3f.ZERO);

    /************************************Modelos 3DS cargados*********************************/
    mMMenu = new MainMenuState();
    mMMenu.setControlPrincipal(this);
    mMMenu.ponerFondo("imagenes/menuPrincipal.jpg");
    GameStateManager.getInstance().attachChild(mMMenu);
    mMMenu.setActive(true);
    state = new DebugGameState();

    PointLight light = new PointLight();
    light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
    light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
    light.setLocation(new Vector3f(100, 100, 100));
    light.setEnabled(true);

    LightState ls = DisplaySystem.getDisplaySystem().getRenderer().createLightState();
    ls.setEnabled(true);
    ls.attach(light);

    //carrito.updateRenderState();
    model.setRenderState(ls);
    wasminton.setRenderState(ls);
    numinton.setRenderState(ls);
    estadio.setRenderState(ls);
    balinerasState.getRootNode().setRenderState(ls);
    balinerasState.setActive(false);

    /*********************Se añaden los Spatial al estado correspondiente*********************/
    //state.getRootNode().attachChild(carrito);
    balinerasState.getRootNode().attachChild(wasminton);
    balinerasState.getRootNode().attachChild(numinton);
    balinerasState.getRootNode().attachChild(estadio);
    balinerasState.getRootNode().attachChild(model);
    //state.getRootNode().attachChild(estadio);
    //Añadir este nodo al estado q corresponda
    // state.getRootNode().attachChild(colladaModelNode);
    //Actualizar Render State
    /*colladaModelNode.setRenderState(ls);
    colladaModelNode.setLocalScale(Vector3f.UNIT_XYZ.mult(10.0f));
    colladaModelNode.setLocalTranslation(Vector3f.ZERO);*/

    /*Alteraciones para los modelos*/

    /*Alteraciones para carrito*/
    //carrito.updateRenderState();
    /*Alteraciones para carrito*/

    /*Alteraciones para wasminton*/
    Vector3f scaleWasminton = wasminton.getLocalScale().clone();
    model.setLocalScale(scaleWasminton.mult(0.05f));
    numinton.setLocalScale(scaleWasminton.mult(0.3f));
    wasminton.setLocalScale(scaleWasminton.mult(0.05f));

    Vector3f transWasminton = wasminton.getLocalTranslation().clone();
    model.setLocalTranslation(transWasminton.add(new Vector3f(0f, 0f, 0f)));
    numinton.setLocalTranslation(transWasminton.add(new Vector3f(0f, -10f, 0f)));
    wasminton.setLocalTranslation(transWasminton.add(new Vector3f(0f, 12f, 0f)));

    Quaternion wasmintonQuadX = wasminton.getLocalRotation().clone();
    Quaternion wasmintonQuadY = wasminton.getLocalRotation().clone();

    Quaternion rotWasmintonX = wasmintonQuadX.fromAngleAxis((float) -Math.PI / 2, Vector3f.UNIT_X);
    Quaternion rotWasmintonY = wasmintonQuadY.fromAngleAxis((float) -Math.PI / 2, Vector3f.UNIT_Y);

    Matrix3f rotMatrixWasmintonX = rotWasmintonX.toRotationMatrix();
    Matrix3f rotMatrixWasmintonY = rotWasmintonY.toRotationMatrix();

    Quaternion rotWasminton = new Quaternion();

    Matrix3f rotMatrixWasminton = rotMatrixWasmintonX.mult(rotMatrixWasmintonY);

    rotWasminton.fromRotationMatrix(rotMatrixWasminton);

    wasminton.setLocalRotation(rotWasminton);

    /*Quaternion quatModelMd5Wasminton = new Quaternion();

    Quaternion rotModel = quatModelMd5Wasminton.fromAngleAxis((float) Math.PI / 2, Vector3f.UNIT_Z);*/

    //model.setLocalRotation(rotWasminton);

    model.updateRenderState();
    wasminton.updateRenderState();
    /*Alteraciones para wasminton*/

    /*Alteraciones para numinton*/
    numinton.setLocalRotation(numinton.getLocalRotation().fromAngleAxis((float) -Math.PI / 2, Vector3f.UNIT_X));
    numinton.updateRenderState();
    /*Alteraciones para numinton*/

    /*Alteraciones para estadio*/
    Quaternion rotEstadio = wasminton.getLocalRotation();
    rotEstadio.fromAngleAxis((float) -Math.PI / 2, Vector3f.UNIT_X);
    estadio.setLocalRotation(rotEstadio);

    estadio.updateRenderState();
    /*Alteraciones para estadio*/

    /*******************************/

    /*colladaModelNode.setRenderState(wasminton.getRenderState(StateType.Texture));
    colladaModelNode.updateRenderState();*/
    /*****************************************************************************************/
    GameStateManager.getInstance().attachChild(balinerasState);
  }

  public void salir() {
    System.exit(0);
  }

  public void init3d() {
    state.setActive(true);
  }

  public void init3dBalineras() {
    this.balinerasState.setActive(true);
  }

  public void initBalineras() {
    init3dBalineras();
  }

  public void initMachete() {
    Box box = new Box("my box", new Vector3f(0, 0, 0), 2, 2, 2);
    box.setModelBound(new BoundingSphere());
    box.updateModelBound();

    state.getRootNode().attachChild(box);
    box.updateRenderState();
    init3d();
  }
}
